package com.itheima.search.service.impl;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.itheima.search.domain.NewsVO;
import com.itheima.search.domain.SearchParam;
import com.itheima.search.domain.SearchResult;
import com.itheima.search.service.NewsSearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;


@Service
public class NewsSearchServiceImpl implements NewsSearchService {
    @Autowired
    private ElasticsearchClient client;

    /**
     * 分页查询
     *
     * @param searchParam
     * @return
     */
    @Override
    public SearchResult newsSearch(SearchParam searchParam) throws IOException {
        Integer size = searchParam.getPageSize();
        Integer from = (searchParam.getPageNo() - 1) * size;

        // 获取搜索关键词，处理空值
        String keyword = Optional.ofNullable(searchParam.getKeyword())
                .orElse("")
                .trim();

        // 构建搜索请求
        SearchResponse<NewsVO> response = client.search(builder -> {
            builder.index("tb_news");

            // 条件查询：有关键词用multiMatch，无关键词用matchAll
            if (StringUtils.isNotBlank(keyword)) {
                builder.query(qB -> qB.multiMatch(mB ->
                        mB.fields("title", "content")
                                .query(keyword)
                ));
            } else {
                builder.query(qB -> qB.matchAll(mA -> mA));
            }

            // 条件高亮：只在有搜索词时设置高亮
            if (StringUtils.isNotBlank(keyword)) {
                builder.highlight(hB -> hB
                        .fields("title", hFB -> hFB.preTags("<em>").postTags("</em>"))
                        .fields("content", hFB -> hFB.preTags("<em>").postTags("</em>"))
                );
            }

            builder.from(from).size(size);
            return builder;
        }, NewsVO.class);

        // 处理搜索结果
        long total = response.hits().total().value();
        long pages = total % size == 0 ? total / size : total / size + 1;
        List<NewsVO> records = new ArrayList<>();

        List<Hit<NewsVO>> hits = response.hits().hits();
        for (Hit<NewsVO> hit : hits) {
            NewsVO source = hit.source();

            // 处理高亮（只在有搜索词且有高亮结果时）
            if (StringUtils.isNotBlank(keyword) && hit.highlight() != null) {
                // 优先使用title的高亮，如果没有则使用content的高亮
                if (hit.highlight().containsKey("title") && !hit.highlight().get("title").isEmpty()) {
                    String titleHighlight = hit.highlight().get("title").get(0);
                    source.setTitle(titleHighlight);
                }
                if (hit.highlight().containsKey("content") && !hit.highlight().get("content").isEmpty()) {
                    // 如果content有高亮，可以设置到content字段或者做其他处理
                    String contentHighlight = hit.highlight().get("content").get(0);
                    source.setContent(contentHighlight);
                }
            }

            records.add(source);
        }

        return new SearchResult(total, pages, records);
    }

    @Override
    public NewsVO queryNewsById(Long newsId) throws IOException {
        SearchResponse<NewsVO> search = client.search(builder -> builder.index("tb_news").query(qb -> qb.term(tB -> tB.field("newsId").value(newsId))), NewsVO.class);
        List<Hit<NewsVO>> hits = search.hits().hits();
        return hits.get(0).source();
    }
}

